namespace YM {
    export class NodePool {
        private poolDic = new Map<new()=>any,Map<string, PoolList>>();
        private poolFuncDic = new Map<new () => any, [(node,args?:any[]) => void, (node,args?:any[]) => void, (args?: any[]) => any, (node,args?:any[]) => void, any]>()
        public initTypePool<T>(type: new () => T, pushFunc?: (node: T,args?:any[]) => void, popFunc?: (node: T,args?:any[]) => void, createFunc?: (args: any[]) => T, clearFunc?: (node: T,args?:any[]) => void, thisObject?: any) {
            let poolFunc: [(node) => void, (node) => void, (...args: any) => T, (node) => void, any] = this.poolFuncDic.get(type);
            if (!poolFunc) {
                poolFunc = [pushFunc, popFunc, createFunc, clearFunc, thisObject];
                this.poolFuncDic.set(type, poolFunc);
            }
            else {
                console.log(type, "池已初始化");
            }
        }
        public removePool<T>(type:new()=>T,key:string,...args:any[]){
            let typeMap=this.poolDic.get(type);
            if(!typeMap){
                typeMap=new Map<string,PoolList>();
                this.poolDic.set(type,typeMap);
            }
            let pool=typeMap.get(key);
            if(pool){
                let arr=pool.getAarry();
                let poolFunc=this.poolFuncDic.get(type);
                if(poolFunc){
                    for (const pobj of arr) {
                        poolFunc[3].call(poolFunc[4],pobj,args);
                    }
                }
            }
            typeMap.delete(key);
        }
        public push<T>(type: new () => T, node, key:string,...args:any[]) {
            let typeMap=this.poolDic.get(type);
            if(!typeMap){
                typeMap=new Map<string,PoolList>();
                this.poolDic.set(type,typeMap);
            }
            let pool = typeMap.get(key);
            if (!pool) {
                pool = new PoolList();
                typeMap.set(key, pool);
            }
            pool.push(node);

            let poolFunc = this.poolFuncDic.get(type);
            if (poolFunc) {
                poolFunc[0].call(poolFunc[4], node,args);
            }
        }
        public pop<T>(type: new () => T, key:string, ...args: any[]) {
            let typeMap=this.poolDic.get(type);
            if(!typeMap){
                typeMap=new Map<string,PoolList>();
                this.poolDic.set(type,typeMap);
            }
            let pool = typeMap.get(key);
            let poolFunc = this.poolFuncDic.get(type);
            if (!pool) {
                pool = new PoolList();
                typeMap.set(key, pool);
            }
            let popObj = pool.pop();
            if (popObj) {
                if (poolFunc) {
                    poolFunc[1].call(poolFunc[4],popObj,args);
                }
            }
            else {
                if (poolFunc) {
                    popObj = poolFunc[2].call(poolFunc[4], args);
                }
            }
            return popObj as T;
        }
    }
    export class PoolList {
        private arr = new Array();
        public push(node) {
            this.arr.push(node);
        }
        public pop() {
            return this.arr.pop();
        }
        public getAarry(){
            return this.arr;
        }
    }
}